package units.assembly 
{
	import base.*;
	import base.constants.Colors;
	import base.constants.Events;
	import base.constants.Types;
	import control.Camera;
	import flash.utils.Timer;
	import units.vessels.Vessel;
	import appkit.responders.NResponder;
	import flash.events.Event;
	import flash.events.TimerEvent;
	
	public class Builder extends GObject 
	{
		private var father:GObject;
		private var buildType:Class;
		private var valid:Boolean;
		private var bar:ProgBar;
		private var timer:Timer;
		
		override public function hitUpdate(hit:Boolean, shapes:Vector.<GObject>=null, actives:Vector.<GObject>=null):void
		{
			setValid(!hit);
		}
		
		
		/* This enterframe loop will checks for the parent object
		 * colliding the builder object; when this happens, 
		 * kill the loop, start the bar and build process */
		private function on_enterframe(e:Event):void
		{
			if (this.hitTestObject(father))
			{
				finalizeBuild();
				NResponder.remove(Event.ENTER_FRAME, on_enterframe, null);
			}
		}
		
		private function on_timercomplete(e:TimerEvent):void
		{
			var unit:GObject = new buildType();
			unit.x = this.x;
			unit.y = this.y-10;
			NResponder.dispatch(Events.Insert, [unit]);
			NResponder.dispatch(Events.Remove, [this]);
			father.enable();
		}
		
		private function finalizeBuild():void
		{
			bar = new ProgBar(-15, 17, 5);
			addChild( bar);
			timer = new Timer(5000, 1);
			NResponder.addNative(timer, TimerEvent.TIMER_COMPLETE, on_timercomplete);
			timer.start();
			bar.start();
		}
		
		public function stopBuild():void
		{
			shape.clear();
			shape.refresh();
			stopDrag();
			
			/* If this builder object has a parent 
			 * (passed from the object which dispatched the build event)
			 * then move the parent obect to the build point; 
			 * dont build until the parent object arrives
			 * lock the parent for the duration of the build process */
			if (father != null && father.type() == Types.Vessel)
			{
				var off:GPoint = new GPoint(this.x - father.x, this.y - father.y);
				(father as Vessel).add( new GPoint(this.x - off.angleX() * 30, this.y - off.angleY() * 30));
				father.disable();
			}
			NResponder.addNative(this, Event.ENTER_FRAME, on_enterframe);
		}
			
		public function startBuild():void
		{
			setValid(true);
			startDrag(true, Camera.rectD);
		}
		
		private function setValid(v:Boolean):void
		{
			valid = v;
			light(v);
		}
		
		public function isValid():Boolean
		{
			return valid;
		}
		
		private function light(v:Boolean):void
		{
			var color:uint;
			if (v)
				color = Colors.Green
			else
				color = Colors.Red;
				
			shape.clear();
			shape.filter(color, 1, 15);
			shape.refresh();
		}
		
		public function Builder(t:Class, f:GObject=null) 
		{
			var g:GShape = new GShape();
			g.draw(1, 15, 1, Colors.Purple, .4, Colors.Purple, .2);
			g.alpha = .7;
			super(g);
			
			father = f;
			buildType = t;
		}
		
	}

}